package com.zhuhao.design_mode.structural_pattern.decorator;


/**
 * 装饰器具体使用
 *
 * 已有功能coffee，需求：在不改变原有代码的情况下给咖啡添加糖、牛奶
 *
 * ## 1、装饰器模式包含四个核心组件，以 "咖啡加糖加奶" 为例说明：
 * - 抽象组件（component）
 *   - 基础接口或抽象类，是所有组件和装饰器的父类
 *   - coffee接口定义
 * - 具体组件（ConcreteComponent）
 *   - 基础接口的实现类
 *   - Coffee的实现类，blackCoffee类
 * - 抽象装饰器（Decorator）
 *   - 继承抽象组件，且持有抽象组件的引用（组合关系），所有装饰器的父类
 *   - coffeeDecorate类，可以为coffee额外添加调料
 * - 具体装饰器（concreteDecorate）
 *   - 装饰器的实现类，添加具体的功能
 *   - 为coffee添加糖、牛奶
 * @Author halk
 */
public class DecorateDemo {

    public static void main(String[] args) {
        Coffee blackCoffee = new BlackCoffee();
        System.out.println(blackCoffee.getDescription() + "  " + blackCoffee.getPrice());

        System.out.println();

        //使用装饰模式进行扩展
        Coffee sugarDecorate = new SugarDecorate(blackCoffee);
        System.out.println(sugarDecorate.getDescription() + "  " + sugarDecorate.getPrice());

        System.out.println();

        //使用装饰模式进行扩展
        Coffee milkDecorate = new MilkDecorate(sugarDecorate);
        System.out.println(milkDecorate.getDescription() + "  " + milkDecorate.getPrice());
    }
}


/**
 * coffee类，原有代码
 */
interface Coffee {
    /**
     * 获取咖啡描述
     *
     * @return
     */
    String getDescription();

    /**
     * 获取咖啡价格
     *
     * @return
     */
    Integer getPrice();
}

/**
 * coffee具体实现类，原有代码
 */
class BlackCoffee implements Coffee {

    @Override
    public String getDescription() {
        return "balck coffee";
    }

    @Override
    public Integer getPrice() {
        return 8;
    }
}

/**
 * coffee装饰器父类，开始对原有代码增强
 */
abstract class CoffeeDecorate implements Coffee {

    //持有需要增强的接口引用
    protected Coffee coffee;

    public CoffeeDecorate(Coffee coffee) {
        this.coffee = coffee;
    }

    @Override
    public String getDescription() {
        return coffee.getDescription();
    }

    @Override
    public Integer getPrice() {
        return coffee.getPrice();
    }
}

/**
 * 具体装饰器。添加额外的功能，加糖
 */
class SugarDecorate extends CoffeeDecorate {

    public SugarDecorate(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String getDescription() {
        System.out.println("对原有代码进行增强！描述信息 + 糖");
        return super.getDescription() + " + 糖";
    }

    @Override
    public Integer getPrice() {
        System.out.println("对原有代码进行增强！价格 + 2");
        return super.getPrice() + 2;
    }
}

/**
 * 具体装饰器。添加额外的功能，加牛奶
 */
class MilkDecorate extends CoffeeDecorate {

    public MilkDecorate(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String getDescription() {
        System.out.println("对原有代码进行增强！描述信息 + 牛奶");
        return super.getDescription() + " + 牛奶";
    }

    @Override
    public Integer getPrice() {
        System.out.println("对原有代码进行增强！价格 + 3");
        return super.getPrice() + 3;
    }
}
